﻿using System;
using System.Collections.Generic;
using UnityEngine.SceneManagement;


namespace HEFramework
{
    /// <summary>
    ///
    /// 场景加载器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-12-21 14:52:19
    /// ----------------------------------------
    /// </summary>
    public class SceneLoader : Singleton<SceneLoader>, ISingletonAwake
    {
        private Dictionary<eSceneType, Assets> assets = new();

        public void Awake()
        {
        }

        protected override void Destroy()
        {
            foreach (var value in assets.Values)
            {
                value.Dispose();
            }

            assets.Clear();
        }

        /// <summary>
        /// 读取场景（同步）
        /// </summary>
        /// <param name="_sceneType"></param>
        /// <param name="_assetBundleName"></param>
        /// <param name="_assetName"></param>
        public void LoadSceneSyn(eSceneType _sceneType, string _assetBundleName, string _assetName)
        {
            switch (AssetBundleSettingScriptableObject.Instance.Domain)
            {
                case eDomain.Unity:
                case eDomain.Resources:
                    SceneManager.LoadScene(_assetName);
                    return;
                case eDomain.Streaming:
                case eDomain.Persistent:
                    var a = GetAssets(_sceneType);
                    a.LoadAssetSyn<UnityEngine.Object>(_assetBundleName, null, ResourceConfig.Extension.SCENE);
                    SceneManager.LoadScene(_assetName);
                    break;
            }
        }


        /// <summary>
        /// 读取场景（异步）
        /// </summary>
        /// <param name="_sceneType"></param>
        /// <param name="_assetBundleName"></param>
        /// <param name="_assetName"></param>
        /// <param name="_callback"></param>
        public void LoadSceneAsync(eSceneType _sceneType, string _assetBundleName, string _assetName, Action _callback)
        {
            switch (AssetBundleSettingScriptableObject.Instance.Domain)
            {
                case eDomain.Unity:
                case eDomain.Resources:
                    LoadSceneAsync(_assetName, _callback).Coroutine();
                    return;
                case eDomain.Streaming:
                case eDomain.Persistent:
                    var a = GetAssets(_sceneType);
                    a.LoadAssetAsync<UnityEngine.Object>(_assetBundleName, null, ResourceConfig.Extension.SCENE, _ => { LoadSceneAsync(_assetName, _callback).Coroutine(); });
                    break;
            }
        }


        /// <summary>
        /// 卸载场景（异步）
        /// </summary>
        /// <param name="_sceneType"></param>
        public void UnLoadSceneAsync(eSceneType _sceneType)
        {
            switch (AssetBundleSettingScriptableObject.Instance.Domain)
            {
                case eDomain.Streaming:
                case eDomain.Persistent:
                    var a = GetAssets(_sceneType);
                    a.Dispose();
                    assets.Remove(_sceneType);
                    break;
            }
        }

        /// <summary>
        /// 获取场景对应的资源
        /// </summary>
        /// <param name="_sceneType"></param>
        /// <returns></returns>
        private Assets GetAssets(eSceneType _sceneType)
        {
            Assets a = null;
            assets.TryGetValue(_sceneType, out a);
            if (a == null)
            {
                a = AssetLoader.Instance.GetAssets();
                assets.Add(_sceneType, a);
            }

            return a;
        }

        /// <summary>
        /// 本地异步读取场景
        /// </summary>
        /// <param name="_assetName"></param>
        /// <param name="_callback"></param>
        /// <returns></returns>
        private async HETask LoadSceneAsync(string _assetName, Action _callback)
        {
            await SceneManager.LoadSceneAsync(_assetName);
            _callback?.Invoke();
        }
    }
}